/*
 * Copyright 2016 Elvis Hew
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.elvishew.xlog.internal.util;


import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.bundle.ElementName;
import ohos.interwork.utils.ParcelableEx;
import ohos.utils.PacMap;
import ohos.utils.Sequenceable;
import ohos.utils.net.Uri;

import java.util.Arrays;
import java.util.Set;

/**
 * Utility for formatting object to string.
 */
public class ObjectToStringUtil {

    /**
     * Bundle object to string, the string would be in the format of "Bundle[{...}]".
     * @param bundle bundle
     * @return String
     */
    public static String bundleToString(PacMap bundle) {
        if (bundle == null) {
            return "null";
        }

        StringBuilder b = new StringBuilder(128);
        b.append("Bundle[{");
        bundleToShortString(bundle, b);
        b.append("}]");
        return b.toString();
    }

    /**
     * Intent object to string, the string would be in the format of "Intent { ... }".
     * @param intent intent
     * @return String
     */
    public static String intentToString(Intent intent) {
        if (intent == null) {
            return "null";
        }

        StringBuilder b = new StringBuilder(128);
        b.append("Intent { ");
        intentToShortString(intent, b);
        b.append(" }");
        return b.toString();
    }

    /**
     * bundleToShortString
     * @param bundle bundle
     * @param b StringBuilder
     */
    private static void bundleToShortString(PacMap bundle, StringBuilder b) {
        boolean first = true;
        for (String key : bundle.getKeys()) {
            if (!first) {
                b.append(", ");
            }
            b.append(key).append('=');
            Object value = bundle.getKeys();
            if (value instanceof int[]) {
                b.append(Arrays.toString((int[]) value));
            } else if (value instanceof byte[]) {
                b.append(Arrays.toString((byte[]) value));
            } else if (value instanceof boolean[]) {
                b.append(Arrays.toString((boolean[]) value));
            } else if (value instanceof short[]) {
                b.append(Arrays.toString((short[]) value));
            } else if (value instanceof long[]) {
                b.append(Arrays.toString((long[]) value));
            } else if (value instanceof float[]) {
                b.append(Arrays.toString((float[]) value));
            } else if (value instanceof double[]) {
                b.append(Arrays.toString((double[]) value));
            } else if (value instanceof String[]) {
                b.append(Arrays.toString((String[]) value));
            } else if (value instanceof CharSequence[]) {
                b.append(Arrays.toString((CharSequence[]) value));
            } else if (value instanceof ParcelableEx[]) {
                b.append(Arrays.toString((ParcelableEx[]) value));
            } else if (value instanceof PacMap) {
                b.append(bundleToString((PacMap) value));
            } else {
                b.append(value);
            }
            first = false;
        }
    }


    private static void bundleToShortString(IntentParams bundle, StringBuilder b) {
        boolean first = true;

        for (String key : bundle.keySet()) {
            if (!first) {
                b.append(", ");
            }
            b.append(key).append('=');
            Object value = bundle.getParam(key);
            if (value instanceof int[]) {
                b.append(Arrays.toString((int[]) value));
            } else if (value instanceof byte[]) {
                b.append(Arrays.toString((byte[]) value));
            } else if (value instanceof boolean[]) {
                b.append(Arrays.toString((boolean[]) value));
            } else if (value instanceof short[]) {
                b.append(Arrays.toString((short[]) value));
            } else if (value instanceof long[]) {
                b.append(Arrays.toString((long[]) value));
            } else if (value instanceof float[]) {
                b.append(Arrays.toString((float[]) value));
            } else if (value instanceof double[]) {
                b.append(Arrays.toString((double[]) value));
            } else if (value instanceof String[]) {
                b.append(Arrays.toString((String[]) value));
            } else if (value instanceof CharSequence[]) {
                b.append(Arrays.toString((CharSequence[]) value));
            } else if (value instanceof Sequenceable[]) {
                b.append(Arrays.toString((Sequenceable[]) value));
            } else if (value instanceof PacMap) {
                b.append(bundleToString((PacMap) value));
            } else {
                b.append(value);
            }
            first = false;
        }
    }

    private static void intentToShortString(Intent intent, StringBuilder b) {
        boolean first = true;
        String mAction = intent.getAction();
        if (mAction != null) {
            b.append("act=").append(mAction);
            first = false;
        }
        Set<String> mCategories = intent.getEntities();
        if (mCategories != null) {
            if (!first) {
                b.append(' ');
            }
            first = false;
            b.append("cat=[");
            boolean firstCategory = true;
            for (String c : mCategories) {
                if (!firstCategory) {
                    b.append(',');
                }
                b.append(c);
                firstCategory = false;
            }
            b.append("]");
        }
        Uri mData = intent.getUri();
        if (mData != null) {
            if (!first) {
                b.append(' ');
            }
            first = false;
            b.append("dat=");

            String scheme = mData.getScheme();
            if (scheme != null) {
                if (scheme.equalsIgnoreCase("tel")) {
                    b.append("tel:xxx-xxx-xxxx");
                } else if (scheme.equalsIgnoreCase("smsto")) {
                    b.append("smsto:xxx-xxx-xxxx");
                } else {
                    b.append(mData);
                }
            } else {
                b.append(mData);
            }
        }
        String mType = intent.getType();
        if (mType != null) {
            if (!first) {
                b.append(' ');
            }
            first = false;
            b.append("typ=").append(mType);
        }
        int mFlags = intent.getFlags();
        if (mFlags != 0) {
            if (!first) {
                b.append(' ');
            }
            first = false;
            b.append("flg=0x").append(Integer.toHexString(mFlags));
        }
        String mPackage = intent.getBundle();
        if (mPackage != null) {
            if (!first) {
                b.append(' ');
            }
            first = false;
            b.append("pkg=").append(mPackage);
        }
        ElementName mComponent = intent.getElement();
//        if (mComponent != null) {
//            if (!first) {
//                b.append(' ');
//            }
//            first = false;
//            b.append("cmp=").append(mComponent.fflattenToShortString());
//        }
//        Rect mSourceBounds = intent.getSourceBounds();
//        if (mSourceBounds != null) {
//            if (!first) {
//                b.append(' ');
//            }
//            first = false;
//            b.append("bnds=").append(mSourceBounds.toShortString());
//        }
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//            ClipData mClipData = intent.getClipData();
//            if (mClipData != null) {
//                if (!first) {
//                    b.append(' ');
//                }
//                first = false;
//                b.append("(has clip)");
//            }
//        }
        IntentParams mExtras = intent.getParams();
        if (mExtras != null) {
            if (!first) {
                b.append(' ');
            }
            b.append("extras={");
            bundleToShortString(mExtras, b);
            b.append('}');
        }
//        if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
//            Intent mSelector = intent.getSelector();
//            if (mSelector != null) {
//                b.append(" sel=");
//                intentToShortString(mSelector, b);
//                b.append("}");
//            }
//        }
    }

    private static String uriToSafeString(Uri uri) {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
//            try {
//                Method toSafeString = Uri.class.getDeclaredMethod("toSafeString");
//                toSafeString.setAccessible(true);
//                return (String) toSafeString.invoke(uri);
//            } catch (NoSuchMethodException e) {
//                e.printStackTrace();
//            } catch (InvocationTargetException e) {
//                e.printStackTrace();
//            } catch (IllegalAccessException e) {
//                e.printStackTrace();
//            }
//        }
        return "";
    }
}
